package com.fitbet.entity.bet;

import java.beans.Transient;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.commons.lang3.StringUtils;
import com.demo2do.core.format.PersistentFormat;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fitbet.entity.user.User;
/**
 * 小赌局
 * @author sjh
 *
 */

@Entity
@Table(name = "user_bet")
@PersistentFormat
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class UserBet {
    
    @Id
    @GeneratedValue
    private Long id;
    
    /**
     * 大赌局
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JsonIdentityReference(alwaysAsId=true)
    private Bet bet;
    
    /**
     * 参与人
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JsonIdentityReference(alwaysAsId=true)
    private User user;
     
    private Float beforeWeight;
    
    private String beforeVedio;
    
    private String beforeVedioReason;
    
    private Float afterWeight;
    
    private String afterVedio;
    
    private String afterVedioReason;
     
    /**
     * 参与时间
     */
    private Date createTime;
    
    
    /**
     * 小赌局奖金池
     * 
     */
    private int bonus;
    
    
    /**
     * 状态
     */
    @Enumerated(EnumType.ORDINAL)
    private UserBetStatus status;
    
    /**
     * 是否成功
     */
    @Column(name = "is_success")
    private boolean success;
    
    /**
     * 大赌局赢的奖金
     */
    private int betResult;
    
    /**
     * 小赌局赢得奖金
     */
    private int supportResult;
    
    /**
     * 看好人数
     */
    private int thumbup;
    
    /**
     * 不被看好人数
     */
    private int  thumbdown;
    
    @Column(name = "is_disabled")
    private boolean disabled;


    
    /**
     * The default constructor
     */
    public UserBet() {
        
    }
    
    /**
     * 
     * @param price
     * @return
     */
    public UserBet income(int price) {
    	this.supportResult =price;
    	return this;
    }
    
    /**
     * 
     * @param success
     * @return
     */
    public UserBet closes(boolean success) {
    	this.success = success;
		this.status = UserBetStatus.FINISHED;
    	return this;
    }
    
    /**
     * 
     * @return
     */
    public UserBet afresh() {
    	this.status = UserBetStatus.CLOSEFAILED;
    	return this;
    }
    
    /**
     * 
     * @return
     */
    public UserBet failure() {
    	this.status = UserBetStatus.OPENFAILED;
    	return  this;
    	
    }
    
    /**
     * 
     * @param passed
     * @return
     */
    public UserBet auth(boolean passed) {
		if(passed) {
			this.status = UserBetStatus.PROCESSING;
		} else {
			this.status = UserBetStatus.OPENFAILED;
		}
		return this;
    	
    }
    
    /**
     * 
     * @param user
     * @param bet
     */
    public UserBet(User user, Bet bet) {
        this.user = user;
        this.bet = bet;
        this.status = UserBetStatus.CREATED;
    }
    
    /**
     * 
     * @return
     */
    public UserBet init() {
        this.createTime = new Date();
        this.bonus = 0;
        this.success = false;
        this.betResult = 0;
        this.supportResult = 0;
        this.thumbup = 0;
        this.thumbdown = 0;
        this.disabled = false;
        this.status = UserBetStatus.CREATED;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public UserBet open() {
        this.status = UserBetStatus.OPEN;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public UserBet processing() {
        this.status = UserBetStatus.PROCESSING;
        return this;
    }
    
    public UserBet close() {
        this.status = UserBetStatus.CLOSE;
        return this;
    }
    
    /**
     * 
     * @param video
     * @param phase
     * @return
     */
    public UserBet updateVideo(String video, String phase, String status) {
        if(StringUtils.equalsIgnoreCase(phase, "open")) {
            this.beforeVedio = video;
            if(StringUtils.equalsIgnoreCase(status, "reupload")) {
                this.status = UserBetStatus.OPEN;
            }
        } else {
            this.afterVedio = video;
            if(StringUtils.equalsIgnoreCase(status, "reupload")) {
                this.status = UserBetStatus.CLOSE;
            }
        }
        
        return this;
    }
    
    /**
     * 
     * @param weight
     * @param phase
     * @return
     */
    public UserBet updateWeight(Float weight, String phase) {
        if(StringUtils.equalsIgnoreCase(phase, "open")) {
            this.beforeWeight = weight;
        } else {
            this.afterWeight = weight;
        }
        
        return this;
    }
    
    /**
     * 
     * @param support
     * @param price
     * @return
     */
    public UserBet support(boolean support, int price) {
        if(support) {
            this.thumbup = this.thumbup + 1;
        } else {
            this.thumbdown = this.thumbdown + 1;
        }
        this.bonus = this.bonus + price;
        
        return this;
    }
    
    /**
     * 
     * @return
     */
    public Map<String, Object> getBets() {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("betId", this.bet.getId());
        parameters.put("betAvatar", this.bet.getAvatar());
        parameters.put("betName", this.bet.getName());
        parameters.put("betStartDate", this.bet.getStartDate());
        parameters.put("betEndDate", this.bet.getEndDate());
        parameters.put("betStatus", this.bet.getStatus());
        parameters.put("betBonus", this.bet.getBetBonus());
        parameters.put("betThumbAmount", this.bet.getThumbAmount());
        return parameters;
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public List<String> getSupportSplit() {
        int total = this.thumbdown + this.thumbup;
        String thumbAmountString = new BigDecimal(total).toString();
        char[] chars = thumbAmountString.toCharArray();
        List<String> result = new LinkedList<>();
        for(int i = 0;i<chars.length;i++){
            char item = chars[i];
            result.add(String.valueOf(item));
        }
        return result;
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public int getPercent() {
        int total = this.thumbdown + this.thumbup;
        if(total != 0) {
            BigDecimal sum = new BigDecimal(this.thumbdown).add(new BigDecimal(this.thumbup));
            BigDecimal result = new BigDecimal(this.thumbup).divide(sum, 2, RoundingMode.CEILING);
            return result.multiply(new BigDecimal(100)).intValue();
        } else {
            return 0;
        }
    }
    
    @Transient
    public int getUpPercent() {
        int total = this.thumbdown + this.thumbup;
        if(total != 0) {
            BigDecimal sum = new BigDecimal(this.thumbdown).add(new BigDecimal(this.thumbup));
            BigDecimal result = new BigDecimal(this.thumbup).divide(sum, 2, RoundingMode.CEILING);
            return result.multiply(new BigDecimal(100)).intValue();
        } else {
            return 0;
        }
    }
    
    @Transient
    public int getDownPercent() {
        int total = this.thumbdown + this.thumbup;
        if(total != 0) {
            BigDecimal sum = new BigDecimal(this.thumbdown).add(new BigDecimal(this.thumbup));
            BigDecimal result = new BigDecimal(this.thumbdown).divide(sum, 2, RoundingMode.CEILING);
            return result.multiply(new BigDecimal(100)).intValue();
        } else {
            return 0;
        }
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public List<String> getBonusSplit() {
        String bonusString = ((new BigDecimal(this.bonus).divide(new BigDecimal(100)).setScale(0))).toString();
        char[] chars = bonusString.toCharArray();
        List<String> result = new LinkedList<>();
        for(int i = 0;i<chars.length;i++){
            char item = chars[i];
            result.add(String.valueOf(item));
        }
        return result;
    }
    
    @Transient
    public List<String> getBonusResultSplit() {
        
        List<String> result = new LinkedList<>();
        if(this.betResult == 0 && this.supportResult == 0) {
            result.add("0");
            return result;
        }
            
        String bonusString = ((new BigDecimal(this.betResult).add(new BigDecimal(this.supportResult))).divide(new BigDecimal(100)).setScale(0)).toString();
        char[] chars = bonusString.toCharArray();
        
        for(int i = 0;i<chars.length;i++){
            char item = chars[i];
            result.add(String.valueOf(item));
        }
        return result;
    }
    
    /**
     * 
     * @return
     */
    public int getSupportUsers () {
        return this.thumbdown + this.thumbup;
    }


    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }


    /**
     * @return the bet
     */
    public Bet getBet() {
        return bet;
    }


    /**
     * @return the user
     */
    public User getUser() {
        return user;
    }


    /**
     * @return the beforeWeight
     */
    public Float getBeforeWeight() {
        return beforeWeight;
    }


    /**
     * @return the beforeVedio
     */
    public String getBeforeVedio() {
        return beforeVedio;
    }


    /**
     * @return the beforeVedioReason
     */
    public String getBeforeVedioReason() {
        return beforeVedioReason;
    }


    /**
     * @return the afterWeight
     */
    public Float getAfterWeight() {
        return afterWeight;
    }


    /**
     * @return the afterVedio
     */
    public String getAfterVedio() {
        return afterVedio;
    }


    /**
     * @return the afterVedioReason
     */
    public String getAfterVedioReason() {
        return afterVedioReason;
    }


    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return createTime;
    }


    /**
     * @return the bonus
     */
    public int getBonus() {
        return bonus;
    }


    /**
     * @return the status
     */
    public UserBetStatus getStatus() {
        return status;
    }


    /**
     * @return the success
     */
    public boolean isSuccess() {
        return success;
    }


    /**
     * @return the betResult
     */
    public int getBetResult() {
        return betResult;
    }


    /**
     * @return the supportResult
     */
    public int getSupportResult() {
        return supportResult;
    }


    /**
     * @return the thumbup
     */
    public int getThumbup() {
        return thumbup;
    }


    /**
     * @return the thumbdown
     */
    public int getThumbdown() {
        return thumbdown;
    }


    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }


    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }


    /**
     * @param bet the bet to set
     */
    public void setBet(Bet bet) {
        this.bet = bet;
    }


    /**
     * @param user the user to set
     */
    public void setUser(User user) {
        this.user = user;
    }


    /**
     * @param beforeWeight the beforeWeight to set
     */
    public void setBeforeWeight(Float beforeWeight) {
        this.beforeWeight = beforeWeight;
    }


    /**
     * @param beforeVedio the beforeVedio to set
     */
    public void setBeforeVedio(String beforeVedio) {
        this.beforeVedio = beforeVedio;
    }


    /**
     * @param beforeVedioReason the beforeVedioReason to set
     */
    public void setBeforeVedioReason(String beforeVedioReason) {
        this.beforeVedioReason = beforeVedioReason;
    }


    /**
     * @param afterWeight the afterWeight to set
     */
    public void setAfterWeight(Float afterWeight) {
        this.afterWeight = afterWeight;
    }


    /**
     * @param afterVedio the afterVedio to set
     */
    public void setAfterVedio(String afterVedio) {
        this.afterVedio = afterVedio;
    }


    /**
     * @param afterVedioReason the afterVedioReason to set
     */
    public void setAfterVedioReason(String afterVedioReason) {
        this.afterVedioReason = afterVedioReason;
    }


    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }


    /**
     * @param bonus the bonus to set
     */
    public void setBonus(int bonus) {
        this.bonus = bonus;
    }


    /**
     * @param status the status to set
     */
    public void setStatus(UserBetStatus status) {
        this.status = status;
    }


    /**
     * @param success the success to set
     */
    public void setSuccess(boolean success) {
        this.success = success;
    }


    /**
     * @param betResult the betResult to set
     */
    public void setBetResult(int betResult) {
        this.betResult = betResult;
    }


    /**
     * @param supportResult the supportResult to set
     */
    public void setSupportResult(int supportResult) {
        this.supportResult = supportResult;
    }


    /**
     * @param thumbup the thumbup to set
     */
    public void setThumbup(int thumbup) {
        this.thumbup = thumbup;
    }


    /**
     * @param thumbdown the thumbdown to set
     */
    public void setThumbdown(int thumbdown) {
        this.thumbdown = thumbdown;
    }


    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }
}
